package com.wande.dataplatform.filecollection.security;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.regex.Pattern;

/**
 * 数据脱敏工具类
 * 提供常见敏感数据的脱敏处理
 *
 * @author wande
 */
@Slf4j
public class DataMaskingUtil {

    /**
     * 手机号正则
     */
    private static final Pattern MOBILE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");

    /**
     * 身份证号正则
     */
    private static final Pattern ID_CARD_PATTERN = Pattern.compile("^\\d{17}[\\dXx]$");

    /**
     * 邮箱正则
     */
    private static final Pattern EMAIL_PATTERN = Pattern.compile("^[\\w.-]+@[\\w.-]+\\.\\w+$");

    /**
     * 银行卡号正则
     */
    private static final Pattern BANK_CARD_PATTERN = Pattern.compile("^\\d{16,19}$");

    /**
     * 脱敏手机号
     * 保留前3位和后4位，中间用****代替
     * 例如：138****5678
     *
     * @param mobile 手机号
     * @return 脱敏后的手机号
     */
    public static String maskMobile(String mobile) {
        if (StrUtil.isBlank(mobile) || !MOBILE_PATTERN.matcher(mobile).matches()) {
            return mobile;
        }
        return mobile.substring(0, 3) + "****" + mobile.substring(7);
    }

    /**
     * 脱敏身份证号
     * 保留前6位和后4位，中间用********代替
     * 例如：110101********1234
     *
     * @param idCard 身份证号
     * @return 脱敏后的身份证号
     */
    public static String maskIdCard(String idCard) {
        if (StrUtil.isBlank(idCard) || !ID_CARD_PATTERN.matcher(idCard).matches()) {
            return idCard;
        }
        return idCard.substring(0, 6) + "********" + idCard.substring(14);
    }

    /**
     * 脱敏邮箱
     * 保留邮箱前缀的前2位和@后面的域名，中间用***代替
     * 例如：ab***@example.com
     *
     * @param email 邮箱
     * @return 脱敏后的邮箱
     */
    public static String maskEmail(String email) {
        if (StrUtil.isBlank(email) || !EMAIL_PATTERN.matcher(email).matches()) {
            return email;
        }
        
        int atIndex = email.indexOf('@');
        if (atIndex <= 2) {
            return "***" + email.substring(atIndex);
        }
        
        return email.substring(0, 2) + "***" + email.substring(atIndex);
    }

    /**
     * 脱敏银行卡号
     * 保留前4位和后4位，中间用********代替
     * 例如：6222********1234
     *
     * @param bankCard 银行卡号
     * @return 脱敏后的银行卡号
     */
    public static String maskBankCard(String bankCard) {
        if (StrUtil.isBlank(bankCard) || !BANK_CARD_PATTERN.matcher(bankCard).matches()) {
            return bankCard;
        }
        
        int length = bankCard.length();
        return bankCard.substring(0, 4) + "********" + bankCard.substring(length - 4);
    }

    /**
     * 脱敏姓名
     * 保留姓氏，名字用*代替
     * 例如：张**
     *
     * @param name 姓名
     * @return 脱敏后的姓名
     */
    public static String maskName(String name) {
        if (StrUtil.isBlank(name)) {
            return name;
        }
        
        if (name.length() == 1) {
            return name;
        } else if (name.length() == 2) {
            return name.charAt(0) + "*";
        } else {
            return name.charAt(0) + "*".repeat(name.length() - 1);
        }
    }

    /**
     * 脱敏地址
     * 保留省市，详细地址用****代替
     * 例如：北京市朝阳区****
     *
     * @param address 地址
     * @return 脱敏后的地址
     */
    public static String maskAddress(String address) {
        if (StrUtil.isBlank(address)) {
            return address;
        }
        
        if (address.length() <= 6) {
            return address;
        }
        
        return address.substring(0, 6) + "****";
    }

    /**
     * 脱敏密码
     * 全部用******代替
     *
     * @param password 密码
     * @return 脱敏后的密码
     */
    public static String maskPassword(String password) {
        if (StrUtil.isBlank(password)) {
            return password;
        }
        return "******";
    }

    /**
     * 通用脱敏
     * 保留前后各n位，中间用*代替
     *
     * @param str 字符串
     * @param prefixLen 前缀保留长度
     * @param suffixLen 后缀保留长度
     * @return 脱敏后的字符串
     */
    public static String mask(String str, int prefixLen, int suffixLen) {
        if (StrUtil.isBlank(str)) {
            return str;
        }
        
        int length = str.length();
        if (length <= prefixLen + suffixLen) {
            return str;
        }
        
        int maskLen = length - prefixLen - suffixLen;
        return str.substring(0, prefixLen) + "*".repeat(maskLen) + str.substring(length - suffixLen);
    }

    /**
     * 自动识别并脱敏
     * 根据字段名自动判断敏感类型并脱敏
     *
     * @param fieldName 字段名
     * @param value 字段值
     * @return 脱敏后的值
     */
    public static String autoMask(String fieldName, String value) {
        if (StrUtil.isBlank(value)) {
            return value;
        }
        
        String lowerFieldName = fieldName.toLowerCase();
        
        // 手机号
        if (lowerFieldName.contains("mobile") || lowerFieldName.contains("phone")) {
            return maskMobile(value);
        }
        
        // 身份证号
        if (lowerFieldName.contains("idcard") || lowerFieldName.contains("id_card")) {
            return maskIdCard(value);
        }
        
        // 邮箱
        if (lowerFieldName.contains("email") || lowerFieldName.contains("mail")) {
            return maskEmail(value);
        }
        
        // 银行卡号
        if (lowerFieldName.contains("bankcard") || lowerFieldName.contains("bank_card") || 
            lowerFieldName.contains("cardno")) {
            return maskBankCard(value);
        }
        
        // 姓名
        if (lowerFieldName.contains("name") && !lowerFieldName.contains("username")) {
            return maskName(value);
        }
        
        // 地址
        if (lowerFieldName.contains("address") || lowerFieldName.contains("addr")) {
            return maskAddress(value);
        }
        
        // 密码
        if (lowerFieldName.contains("password") || lowerFieldName.contains("pwd")) {
            return maskPassword(value);
        }
        
        return value;
    }
}
